package de.rj.urwalking.data.survey;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;

import de.rj.urwalking.config.Constants;

public class Scale implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int id;
	private String name;
	private boolean extremityOnly;
	private boolean isPictureBased;

	private ArrayList<ScalePoint> scalePoints = new ArrayList<ScalePoint>();

	public Scale(int id, String name, boolean extremityOnly, boolean isPictureBased) {
		this.id = id;
		this.name = name;
		this.extremityOnly = extremityOnly;
		this.isPictureBased = isPictureBased;
	}

	public void addScalePoint(String name, int intValue, int pictureId, boolean isIndoor, boolean isOutdoor) {
		scalePoints.add(new ScalePoint(name, intValue, pictureId, isIndoor, isOutdoor));

	}

	public ArrayList<ScalePoint> getScalePoints() {
		return scalePoints;
	}

	public boolean isPictureBased() {
		return isPictureBased;
	}

	public int getValueForPictureId(int pictureId) {
		for (ScalePoint scalePoint : scalePoints) {

			if (scalePoint.getPictureId() == pictureId) {
				return scalePoint.getIntValue();
			}
		}
		return Constants.UNDEFINED;
	}
	
	public int getPictureIdForValue(int value) {
		for (ScalePoint scalePoint : scalePoints) {

			if (scalePoint.getIntValue() == value) {
				return scalePoint.getPictureId();
			}
		}
		return Constants.UNDEFINED;
	}
	
	/**
	 * Finds and returns the {@link ScalePoint} with integer value one.
	 * 
	 */
	public ScalePoint getLeftExtreme() {
		for (ScalePoint sp : scalePoints) {
			if (sp.getIntValue() == 1) {
				return sp;
			}
		}
		return null;
	}

	/**
	 * Returns the {@link ScalePoint} with the highest integer value.
	 */
	public ScalePoint getRightExtreme() {
		ScalePoint max = null;
		
		for (ScalePoint sp : scalePoints) {
			
			if (max == null || sp.getIntValue() > max.getIntValue()) {
				max = sp;
			}
		}
		return max;
	}

	/**
	 * Finds and returns all {@link ScalePoint}s whose integer value is not negative.
	 * 
	 * @return An {@link ArrayList} containing the ScalePoints
	 */
	public ArrayList<ScalePoint> getRegularScalePoints() {
		ArrayList<ScalePoint> regularScalePoints = new ArrayList<ScalePoint>();

		for (ScalePoint sp : scalePoints) {
			if (sp.getIntValue() >= 0) {
				regularScalePoints.add(sp);
			}
		}

		// add the missing scalepoints between the lowest and the highest one

		int minIntValue = Collections.min(regularScalePoints).getIntValue();
		int maxIntValue = Collections.max(regularScalePoints).getIntValue();

		if (extremityOnly) {
			for (int i = minIntValue + 1; i < maxIntValue; i++) {
				regularScalePoints.add(new ScalePoint("", i));
			}
			Collections.sort(regularScalePoints);
		}
		return regularScalePoints;
	}

	/**
	 * Finds and returns all {@link ScalePoint}s whose integer value is below zero.
	 * 
	 * @return An {@link ArrayList} containing the ScalePoints
	 */
	public ArrayList<ScalePoint> getAdditionalScalePoints() {
		ArrayList<ScalePoint> additionalScalePoints = new ArrayList<ScalePoint>();

		for (ScalePoint sp : scalePoints) {
			if (sp.getIntValue() < 0) {
				additionalScalePoints.add(sp);
			}
		}
		return additionalScalePoints;
	}
}
